<template>
    <view
        v-if="show"
        class="uni-noticebar"
        :style="{ backgroundColor: backgroundColor }"
        @click="onClick"
    >
        <!-- #ifdef MP-ALIPAY -->
        <view
            v-if="showClose === true || showClose === 'true'"
            class="uni-noticebar-close"
            @click="close"
        >
            <icons type="closeempty" :color="color" size="12" />
        </view>
        <view
            v-if="showIcon === true || showIcon === 'true'"
            class="uni-noticebar-icon"
        >
            <icons type="sound" :color="color" size="14" />
        </view>
        <!-- #endif -->
        <!-- #ifndef MP-ALIPAY -->
        <icons
            v-if="showClose === true || showClose === 'true'"
            class="uni-noticebar-close"
            type="closeempty"
            :color="color"
            size="12"
            @click="close"
        />
        <icons
            v-if="showIcon === true || showIcon === 'true'"
            class="uni-noticebar-icon"
            type="sound"
            :color="color"
            size="14"
        />
        <!-- #endif -->
        <view
            ref="textBox"
            class="uni-noticebar__content-wrapper"
            :class="{
                'uni-noticebar__content-wrapper--scrollable': scrollable,
                'uni-noticebar__content-wrapper--single':
                    !scrollable && (single || moreText),
            }"
        >
            <view
                :id="elIdBox"
                class="uni-noticebar__content"
                :class="{
                    'uni-noticebar__content--scrollable': scrollable,
                    'uni-noticebar__content--single':
                        !scrollable && (single || moreText),
                }"
            >
                <text
                    :id="elId"
                    ref="animationEle"
                    class="uni-noticebar__content-text"
                    :class="{
                        'uni-noticebar__content-text--scrollable': scrollable,
                        'uni-noticebar__content-text--single':
                            !scrollable && (single || moreText),
                    }"
                    :style="{
                        color: color,
                        width: wrapWidth + 'px',
                        animationDuration: animationDuration,
                        '-webkit-animationDuration': animationDuration,
                        animationPlayState: webviewHide
                            ? 'paused'
                            : animationPlayState,
                        '-webkit-animationPlayState': webviewHide
                            ? 'paused'
                            : animationPlayState,
                        animationDelay: animationDelay,
                        '-webkit-animationDelay': animationDelay,
                    }"
                    >{{ text }}</text
                >
            </view>
        </view>
        <view
            v-if="showGetMore === true || showGetMore === 'true'"
            class="uni-noticebar__more"
            @click="clickMore"
        >
            <text
                v-if="moreText"
                :style="{ color: moreColor }"
                class="uni-noticebar__more-text"
                >{{ moreText }}</text
            >
            <icons type="arrowright" :color="moreColor" size="14" />
        </view>
    </view>
</template>

<script>
    import icons from "./icons.vue";
    // #ifdef APP-NVUE
    const dom = weex.requireModule("dom");
    const animation = weex.requireModule("animation");
    // #endif

    /**
     * NoticeBar 自定义导航栏
     * @description 通告栏组件
     * @tutorial https://ext.dcloud.net.cn/plugin?id=30
     * @property {Number} speed 文字滚动的速度，默认100px/秒
     * @property {String} text 显示文字
     * @property {String} backgroundColor 背景颜色
     * @property {String} color 文字颜色
     * @property {String} moreColor 查看更多文字的颜色
     * @property {String} moreText 设置“查看更多”的文本
     * @property {Boolean} single = [true|false] 是否单行
     * @property {Boolean} scrollable = [true|false] 是否滚动，为true时，NoticeBar为单行
     * @property {Boolean} showIcon = [true|false] 是否显示左侧喇叭图标
     * @property {Boolean} showClose = [true|false] 是否显示左侧关闭按钮
     * @property {Boolean} showGetMore = [true|false] 是否显示右侧查看更多图标，为true时，NoticeBar为单行
     * @event {Function} click 点击 NoticeBar 触发事件
     * @event {Function} close 关闭 NoticeBar 触发事件
     * @event {Function} getmore 点击”查看更多“时触发事件
     */

    export default {
        name: "NoticeBar",
        components: {
            icons,
        },
        props: {
            text: {
                type: String,
                default: "",
            },
            moreText: {
                type: String,
                default: "",
            },
            backgroundColor: {
                type: String,
                default: "#fffbe8",
            },
            speed: {
                // 默认1s滚动100px
                type: Number,
                default: 100,
            },
            color: {
                type: String,
                default: "#de8c17",
            },
            moreColor: {
                type: String,
                default: "#999999",
            },
            single: {
                // 是否单行
                type: [Boolean, String],
                default: false,
            },
            scrollable: {
                // 是否滚动，添加后控制单行效果取消
                type: [Boolean, String],
                default: false,
            },
            showIcon: {
                // 是否显示左侧icon
                type: [Boolean, String],
                default: false,
            },
            showGetMore: {
                // 是否显示右侧查看更多
                type: [Boolean, String],
                default: false,
            },
            showClose: {
                // 是否显示左侧关闭按钮
                type: [Boolean, String],
                default: false,
            },
        },
        data() {
            const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`;
            const elIdBox = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`;
            return {
                textWidth: 0,
                boxWidth: 0,
                wrapWidth: "",
                webviewHide: false,
                // #ifdef APP-NVUE
                stopAnimation: false,
                // #endif
                elId: elId,
                elIdBox: elIdBox,
                show: true,
                animationDuration: "none",
                animationPlayState: "paused",
                animationDelay: "0s",
            };
        },
        mounted() {
            // #ifdef APP-PLUS
            var pages = getCurrentPages();
            var page = pages[pages.length - 1];
            var currentWebview = page.$getAppWebview();
            currentWebview.addEventListener("hide", () => {
                this.webviewHide = true;
            });
            currentWebview.addEventListener("show", () => {
                this.webviewHide = false;
            });
            // #endif
            this.$nextTick(() => {
                this.initSize();
            });
        },
        // #ifdef APP-NVUE
        beforeDestroy() {
            this.stopAnimation = true;
        },
        // #endif
        methods: {
            initSize() {
                if (this.scrollable) {
                    // #ifndef APP-NVUE
                    let query = [],
                        boxWidth = 0,
                        textWidth = 0;
                    let textQuery = new Promise((resolve, reject) => {
                        uni.createSelectorQuery()
                            // #ifndef MP-ALIPAY
                            .in(this)
                            // #endif
                            .select(`#${this.elId}`)
                            .boundingClientRect()
                            .exec((ret) => {
                                this.textWidth = ret[0].width;
                                resolve();
                            });
                    });
                    let boxQuery = new Promise((resolve, reject) => {
                        uni.createSelectorQuery()
                            // #ifndef MP-ALIPAY
                            .in(this)
                            // #endif
                            .select(`#${this.elIdBox}`)
                            .boundingClientRect()
                            .exec((ret) => {
                                this.boxWidth = ret[0].width;
                                resolve();
                            });
                    });
                    query.push(textQuery);
                    query.push(boxQuery);
                    Promise.all(query).then(() => {
                        this.animationDuration = `${this.textWidth / this.speed}s`;
                        this.animationDelay = `-${this.boxWidth / this.speed}s`;
                        setTimeout(() => {
                            this.animationPlayState = "running";
                        }, 1000);
                    });
                    // #endif
                    // #ifdef APP-NVUE
                    dom.getComponentRect(this.$refs["animationEle"], (res) => {
                        let winWidth = uni.getSystemInfoSync().windowWidth;
                        this.textWidth = res.size.width;
                        animation.transition(
                            this.$refs["animationEle"],
                            {
                                styles: {
                                    transform: `translateX(-${winWidth}px)`,
                                },
                                duration: 0,
                                timingFunction: "linear",
                                delay: 0,
                            },
                            () => {
                                if (!this.stopAnimation) {
                                    animation.transition(
                                        this.$refs["animationEle"],
                                        {
                                            styles: {
                                                transform: `translateX(-${this.textWidth}px)`,
                                            },
                                            timingFunction: "linear",
                                            duration:
                                                ((this.textWidth - winWidth) /
                                                    this.speed) *
                                                1000,
                                            delay: 1000,
                                        },
                                        () => {
                                            if (!this.stopAnimation) {
                                                this.loopAnimation();
                                            }
                                        }
                                    );
                                }
                            }
                        );
                    });
                    // #endif
                }
                // #ifdef APP-NVUE
                if (!this.scrollable && (this.single || this.moreText)) {
                    dom.getComponentRect(this.$refs["textBox"], (res) => {
                        this.wrapWidth = res.size.width;
                    });
                }
                // #endif
            },
            loopAnimation() {
                // #ifdef APP-NVUE
                animation.transition(
                    this.$refs["animationEle"],
                    {
                        styles: {
                            transform: `translateX(0px)`,
                        },
                        duration: 0,
                    },
                    () => {
                        if (!this.stopAnimation) {
                            animation.transition(
                                this.$refs["animationEle"],
                                {
                                    styles: {
                                        transform: `translateX(-${this.textWidth}px)`,
                                    },
                                    duration: (this.textWidth / this.speed) * 1000,
                                    timingFunction: "linear",
                                    delay: 0,
                                },
                                () => {
                                    if (!this.stopAnimation) {
                                        this.loopAnimation();
                                    }
                                }
                            );
                        }
                    }
                );
                // #endif
            },
            clickMore() {
                this.$emit("getmore");
            },
            close() {
                this.show = false;
                this.$emit("close");
            },
            onClick() {
                this.$emit("click");
            },
        },
    };
</script>

<style lang="scss" scoped>
    .uni-noticebar {
        /* #ifndef APP-NVUE */
        display: flex;
        width: 100%;
        box-sizing: border-box;
        /* #endif */
        flex-direction: row;
        align-items: center;
        padding: 6px 0px;
    }

    .uni-noticebar-close {
        margin-right: 5px;
    }

    .uni-noticebar-icon {
        margin-right: 5px;
    }

    .uni-noticebar__content-wrapper {
        flex: 1;
        flex-direction: column;
        overflow: hidden;
    }

    .uni-noticebar__content-wrapper--single {
        /* #ifndef APP-NVUE */
        line-height: 18px;
        /* #endif */
    }

    .uni-noticebar__content-wrapper--single,
    .uni-noticebar__content-wrapper--scrollable {
        flex-direction: row;
    }

    /* #ifndef APP-NVUE */
    .uni-noticebar__content-wrapper--scrollable {
        position: relative;
        height: 18px;
    }
    /* #endif */

    .uni-noticebar__content--scrollable {
        /* #ifdef APP-NVUE */
        flex: 0;
        /* #endif */
        /* #ifndef APP-NVUE */
        flex: 1;
        display: block;
        overflow: hidden;
        /* #endif */
    }

    .uni-noticebar__content--single {
        /* #ifndef APP-NVUE */
        display: flex;
        flex: none;
        width: 100%;
        justify-content: center;
        /* #endif */
    }

    .uni-noticebar__content-text {
        font-size: 14px;
        line-height: 18px;
        /* #ifndef APP-NVUE */
        word-break: break-all;
        /* #endif */
    }

    .uni-noticebar__content-text--single {
        /* #ifdef APP-NVUE */
        lines: 1;
        /* #endif */
        /* #ifndef APP-NVUE */
        display: block;
        width: 100%;
        white-space: nowrap;
        /* #endif */
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .uni-noticebar__content-text--scrollable {
        /* #ifdef APP-NVUE */
        lines: 1;
        padding-left: 750rpx;
        /* #endif */
        /* #ifndef APP-NVUE */
        position: absolute;
        display: block;
        height: 18px;
        line-height: 18px;
        white-space: nowrap;
        padding-left: 100%;
        animation: notice 10s 0s linear infinite both;
        animation-play-state: paused;
        /* #endif */
    }

    .uni-noticebar__more {
        /* #ifndef APP-NVUE */
        display: inline-flex;
        /* #endif */
        flex-direction: row;
        flex-wrap: nowrap;
        align-items: center;
        padding-left: 5px;
    }

    .uni-noticebar__more-text {
        font-size: 14px;
    }

    @keyframes notice {
        100% {
            transform: translate3d(-100%, 0, 0);
        }
    }
</style>
